package com.atwisdom.star.core.bsl.modelClass.resource.Impl;

import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.actionType.modelClass.resource.ResourceActionType;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.vo.*;
import com.atwisdom.star.core.bsl.aop.ResourceInstanceAnnotation;
import com.atwisdom.star.core.bsl.modelClass.resource.ResourceInstanceBslService;
import com.atwisdom.star.core.dsl.modelClass.resource.Impl.ResourceInstanceDslServiceImpl;
import com.atwisdom.star.exception.pojo.BusinessException;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

@Service
public class ResourceInstanceBslServiceImpl implements ResourceInstanceBslService {
    private ResourceInstanceDslServiceImpl resourceInstanceDslService;

    @Autowired
    public void setResourceInstanceDslService(ResourceInstanceDslServiceImpl resourceInstanceDslService) {
        this.resourceInstanceDslService = resourceInstanceDslService;
    }

    /**
     * 服务工厂方法
     * @param actionDataList 参数
     * @return 参数
     * @throws BusinessException 异常
     */
    @Transactional
    public ResultInfo<?> responseFactory(List<ActionData<JSONObject>> actionDataList) throws BusinessException {
        ResultInfo<?> resultInfo = null;
        for (ActionData<JSONObject> actionData : actionDataList) {
            String action = actionData.getAction();
            ResourceActionType actionType = ResourceActionType.valueOf(action);
            String methodName = actionType.getMethodName();
            resultInfo = this.execMethod(methodName, actionData);
        }
        return resultInfo;
    }

    /**
     * 反射执行业务单元方法
     *
     * @param methodName 方法名
     * @param actionData 方法参数
     * @return 返回结果
     * @throws BusinessException 业务异常
     */
    public ResultInfo<?> execMethod(String methodName, ActionData<JSONObject> actionData) throws BusinessException {
        Class<? extends ResourceInstanceBslServiceImpl> clz = this.getClass();
        try {
            Method method = clz.getMethod(methodName, ActionData.class);
            ResourceInstanceBslServiceImpl service = (ResourceInstanceBslServiceImpl) AopContext.currentProxy();
            return (ResultInfo<?>) method.invoke(service, actionData);
        } catch (NoSuchMethodException ex) {
            throw new BusinessException("999999", "没有找到该方法(" + methodName + ")", ex);
        } catch (IllegalAccessException ex) {
            throw new BusinessException("999999", "没有访问该方法权限(" + methodName + ")", ex);
        } catch (InvocationTargetException ex) {
            Throwable targetException = ex.getTargetException();
            if (targetException instanceof BusinessException) {
                BusinessException bex = (BusinessException) targetException;
                throw new BusinessException("999999", bex.getErrorMsg(), ex);
            } else {
                throw new BusinessException("999999", "出错了请重试：(" + methodName + ")---" + ex.getMessage(), ex);
            }
        }
    }
    /**
     * 查询全部摘要（通用）
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> queryAllInfo(ActionData<JSONObject> actionData) {
        List<JSONObject> jsonObjectList = this.resourceInstanceDslService.queryAllInfo();
        return JsonResult.success(jsonObjectList);
    }

    /**
     * 分页查询全部摘要（通用）
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<PageInfo> queryAllInfoByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.resourceInstanceDslService.queryAllInfoByPage(pageNumber, pageSize, orderBy);
        return JsonResult.success(pageInfo);
    }

    /**
     * 查询全部数据（通用）
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> queryAll(ActionData<JSONObject> actionData) {
        List<JSONObject> jsonObjectList = this.resourceInstanceDslService.queryAll();
        return JsonResult.success(jsonObjectList);
    }

    /**
     * 分页查询全部数据（通用）
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> listAllByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.resourceInstanceDslService.listAllByPage(pageNumber, pageSize, orderBy);
        return JsonResult.success(pageInfo);
    }

    /**
     * 按条件查询模型
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> query(ActionData<JSONObject> actionData) {
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        String orderBy = actionData.getOrderBy();
        List<JSONObject> queryJsonList = this.resourceInstanceDslService.query(condition, className, orderBy);
        return JsonResult.success(queryJsonList);
    }

    /**
     * 按条件分页查询模型实例摘要
     * @param actionData 参数
     * @return 返回结果
     */
    public ResultInfo<?> queryInfoByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.resourceInstanceDslService.queryInfoByPage(pageNumber, pageSize, condition, className, orderBy);
        return JsonResult.success(pageInfo);
    }

    /**
     * 按条件分页查询模型实例
     * @param actionData 参数
     * @return 返回结果
     */
    public ResultInfo<?> queryByPage(ActionData<JSONObject> actionData) {
        int pageNumber = actionData.getPageNumber();
        int pageSize = actionData.getPageSize();
        String condition = actionData.getCondition();
        String className = actionData.getClassName();
        String orderBy = actionData.getOrderBy();
        PageInfo pageInfo = this.resourceInstanceDslService.queryByPage(pageNumber, pageSize, condition, className, orderBy);
        return JsonResult.success(pageInfo);
    }

    /**
     * 根据id数组查询实例数据
     * @param actionData
     * @return
     */
    @Override
    public ResultInfo<List<JSONObject>> queryByIds(ActionData<JSONObject> actionData) {
        List<Long> ids = actionData.getIds();
        List<JSONObject> resultList = resourceInstanceDslService.queryByIds(ids);
        return JsonResult.success(resultList);
    }

    /**
     * 添加新模型
     *
     * @param actionData 参数
     * @return 返回值
     */
    @ResourceInstanceAnnotation
    @Override
    public ResultInfo<?> add(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        JSONObject jsonObject = data.get(0);
        String type = jsonObject.getString("type");
        String className = jsonObject.getString("className");
        String name = jsonObject.getString("name");
        JSONObject values = jsonObject.getJSONObject("values");
        JSONObject addJson = this.resourceInstanceDslService.add(type, className, name,values);
        return JsonResult.success(addJson);
    }

    /**
     * 添加新模型,并初始化web等参数
     *
     * @param actionData 参数
     * @return 返回值
     */
    @ResourceInstanceAnnotation
    @Override
    public ResultInfo<?> addAndInitWeb(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        JSONObject jsonObject = data.get(0);
        String type = jsonObject.getString("type");
        String className = jsonObject.getString("className");
        String name = jsonObject.getString("name");
        JSONObject values = jsonObject.getJSONObject("values");
        JSONObject web = jsonObject.getJSONObject("web");
        JSONObject addJson = this.resourceInstanceDslService.add(type, className, name,values,web);
        return JsonResult.success(addJson);
    }
    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param actionData 参数
     * @return 返回值
     */
    @ResourceInstanceAnnotation
    @Override
    public ResultInfo<?> updateById(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        JSONObject updateJson = JsonUtil.toJSONObject(data.get(0));
        boolean updateNullFlag = actionData.isUpdateNullFlag();
        if(updateNullFlag){
            this.resourceInstanceDslService.updateFieldNullById(updateJson);
        }
        JSONObject jsonObject = this.resourceInstanceDslService.updateById(updateJson);
        return JsonResult.success(jsonObject);
    }

    /**
     * 更新模型属性字段
     * 更新，需要同步更新实例，同步更新历史数据
     * 1、className 和 自定字段
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> updateByIds(ActionData<JSONObject> actionData) {
        List<JSONObject> jsonObjectList = this.resourceInstanceDslService.updateByIds(actionData.getData());
        return JsonResult.success(jsonObjectList);
    }

    /**
     * 更新模型类型和类名（配置阶段）
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> updateClassName(ActionData<JSONObject> actionData) {
        List<JSONObject> data = actionData.getData();
        List<JSONObject> jsonObjectList = this.resourceInstanceDslService.updateClassName(data.get(0));
        return JsonResult.success(jsonObjectList);
    }

    /**
     * 按ids删除模型
     *
     * @param actionData 参数
     * @return 返回值
     */
    @ResourceInstanceAnnotation
    @Override
    public ResultInfo<?> deleteByIds(ActionData<JSONObject> actionData) {
        List<Long> ids = actionData.getIds();
        this.resourceInstanceDslService.deleteByIds(ids);
        return JsonResult.success(StatusCode.SUCCESS);
    }

    /**
     * 接className删除
     * 1、删除实例、2、删除历史 3、更新redis
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> deleteByClassName(ActionData<JSONObject> actionData) {
        String className = actionData.getClassName();
        this.resourceInstanceDslService.deleteByClassName(className);
        return JsonResult.success(StatusCode.SUCCESS);
    }

    /**
     * 批量删除
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> deleteByClassNames(ActionData<JSONObject> actionData) {
        List<String> classNames = actionData.getClassNames();
        this.resourceInstanceDslService.deleteByClassNames(classNames);
        return JsonResult.success(StatusCode.SUCCESS);
    }

    /**
     * 按Id 废除模型
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> repealByIds(ActionData<JSONObject> actionData) {
        List<Long> ids = actionData.getIds();
        this.resourceInstanceDslService.repealByIds(ids);
        return JsonResult.success(StatusCode.SUCCESS);
    }

    /**
     * 批量废除
     *
     * @param actionData 参数
     * @return 返回值
     */
    @Override
    public ResultInfo<?> repealByClassNames(ActionData<JSONObject> actionData) {
        List<String> classNames = actionData.getClassNames();
        this.resourceInstanceDslService.repealByClassNames(classNames);
        return JsonResult.success(StatusCode.SUCCESS);
    }
}
